//
//  SubscribeService+Save.swift
//  NDAi
//
//  Created by 丸子 on 2024/7/3.
//

import Foundation
import StoreKit

extension SubscribeService {
    
    func getPayInfoAccountIdRelateProductId(productId: String) -> Int {
        guard !productId.isEmpty else {
            return 0
        }
        guard let accountIdString = keychainStore.string(forKey: productId), !accountIdString.isEmpty else {
            return 0
        }
        return Int(accountIdString) ?? 0
    }
    
    func savePayInfoProductId(productId: String, relateAccountId accountId: Int) {
        guard !productId.isEmpty else {
            return
        }
        let accountIdString = "\(accountId)"
        keychainStore.setString(accountIdString, forKey: productId)
        _ = keychainStore.synchronizable
    }
    
    func savePayInfo(orderId: String, recipient: String, productId: String) {
        let account = Appearance.shared.accoutModel
        var orderInfo = PaymentTransactionInfo()
        orderInfo.orderId = orderId
        orderInfo.accountId = account?.userId ?? 0
        orderInfo.recipient = recipient
        orderInfo.transactionDate = Date()
        orderInfo.productId = productId
        SqlManager.shared.insert([orderInfo])
    }
    
    func updatePayInfo(orderId: String?, transactionId: String?) {
        guard let orderId = orderId, let transactionId = transactionId else { return }
        guard var orderInfo = SqlManager.shared.filter(from: PaymentTransactionInfo.self, where: PaymentTransactionInfo.Properties.orderId == orderId)?.first else { return }
        orderInfo.transactionId = transactionId
        SqlManager.shared.update(on: [PaymentTransactionInfo.Properties.transactionId], with: orderInfo, where: PaymentTransactionInfo.Properties.orderId == orderId)
    }
    
    func updatePayInfoTransaction(transactionId: String?) {
        guard let transactionId = transactionId else { return }
        guard var orderInfo = SqlManager.shared.filter(from: PaymentTransactionInfo.self, where: PaymentTransactionInfo.Properties.transactionId == transactionId)?.first else { return }
        lock.lock()
        defer {
            lock.unlock()
        }
        orderInfo.isTransactionValidFromService = true
        SqlManager.shared.update(on: [PaymentTransactionInfo.Properties.transactionId], with: orderInfo, where: PaymentTransactionInfo.Properties.orderId == orderId)
    }
    
    func updatePaymentTransactionInfoVerifyCount(withTransactionId transactionId: String?) {
        guard let transactionId = transactionId, !transactionId.isEmpty else {
            return
        }
        guard var orderInfo = SqlManager.shared.filter(from: PaymentTransactionInfo.self, where: PaymentTransactionInfo.Properties.transactionId == transactionId)?.first else { return }
        lock.lock()
        defer {
            lock.unlock()
        }
        if let modelVerifyCount = orderInfo.modelVerifyCount {
            orderInfo.modelVerifyCount = modelVerifyCount + 1
        }else {
            orderInfo.modelVerifyCount = 1
        }
        SqlManager.shared.update(on: [PaymentTransactionInfo.Properties.modelVerifyCount], with: orderInfo, where: PaymentTransactionInfo.Properties.transactionId == transactionId)
    }
    
    func updatePaymentOrderIdInfoVerifyCount(withOrderId orderId: String?) {
        guard let orderId = orderId, !orderId.isEmpty else {
            return
        }
        guard var orderInfo = SqlManager.shared.filter(from: PaymentTransactionInfo.self, where: PaymentTransactionInfo.Properties.orderId == orderId)?.first else { return }
        lock.lock()
        defer {
            lock.unlock()
        }
        if let modelVerifyCount = orderInfo.modelVerifyCount {
            orderInfo.modelVerifyCount = modelVerifyCount + 1
        }else {
            orderInfo.modelVerifyCount = 1
        }
        SqlManager.shared.update(on: [PaymentTransactionInfo.Properties.modelVerifyCount], with: orderInfo, where: PaymentTransactionInfo.Properties.orderId == orderId)
    }
    
    
    func savePaymentTransactionInfoIfNeed(transaction: SKPaymentTransaction?) {
        guard let transaction = transaction else {
            return
        }
        guard let transactionId = transaction.transactionIdentifier else {
            return
        }
        lock.lock()
        defer { lock.unlock() }
        if SqlManager.shared.exist(where: PaymentTransactionInfo.Properties.transactionId == transactionId, from: PaymentTransactionInfo.self) {
            return
        } else {
            var transactionInfo = PaymentTransactionInfo()
            let account = Appearance.shared.accoutModel
            let productId = transaction.payment.productIdentifier
            let orderId = transaction.payment.applicationUsername
            transactionInfo.transactionId = transactionId
            transactionInfo.accountId = account?.userId ?? 0
            transactionInfo.orderId = orderId
            transactionInfo.transactionDate = Date()
            transactionInfo.productId = productId
            if orderId == nil && transactionInfo.accountId == 0 {
                transactionInfo.accountId = getPayInfoAccountIdRelateProductId(productId: productId)
            }
            transactionInfo.md5 = nil
            transactionInfo.modelVerifyCount = 0
            transactionInfo.isTransactionValidFromService = false
            SqlManager.shared.insert([transactionInfo])
        }
    }
    func deletePaymentTransactionInfoAfterVerify(transactionId: String?) {
        guard let transactionId = transactionId else {
            return
        }
        lock.lock()
        defer { lock.unlock() }
        SqlManager.shared.delete(from: PaymentTransactionInfo.self, where: PaymentTransactionInfo.Properties.transactionId == transactionId)
    }
    
}
